package com.kifas.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import javax.mail.internet.MimeMessage;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import javax.xml.bind.JAXBElement;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import com.kifas.entity.StokOpnameEntity;
import com.kifas.model.xml.MailConfigurationModel;
import com.kifas.model.xml.MailStatus;
import com.kifas.service.EntityServiceManager;
import com.kifas.utils.PropertyUtil;
import com.kifas.utils.StokOpnameMailGenerator;

@Component
@Scope("prototype")
@Path("/Mail")
public class MailController {

	private final static Logger log = Logger.getLogger(MailController.class);
	
	private final static String MAIL_HOST = "mail.host";
	private final static String MAIL_PORT = "mail.port";
	private final static String MAIL_USER = "mail.username";
	private final static String MAIL_PASSWORD = "mail.password";
	private final static String MAIL_AUTH = "mail.smtp.auth";
	private final static String MAIL_TLS = "mail.smtp.starttls.enable";
	private final static String MAIL_SENDER = "mail.sender";
	private final static String MAIL_RECIPIENT = "mail.recipient";
	private final static String MAIL_SUBJECT = "mail.subject";
	
	@Context
	UriInfo uriInfo;

	@Autowired
	private EntityServiceManager entityManager;
	
	@Autowired
	private JavaMailSender javaMailSender;
	
	@Autowired
	private SimpleMailMessage simpleMailMessage;
	
	@Autowired
	private PropertyUtil propertyUtil;

	@GET
	@Path("SendStokReport")
	@Produces(MediaType.APPLICATION_XML)
	public MailStatus sendStokReport() {
		MimeMessage mimeMessage = javaMailSender.createMimeMessage();
		List<StokOpnameEntity> stokOpnames = entityManager.getStokOpnames();
		StokOpnameMailGenerator stokMailGenerator = new StokOpnameMailGenerator(stokOpnames);
		try {
			MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);
			helper.setFrom(simpleMailMessage.getFrom());
			helper.setTo(simpleMailMessage.getTo());
			helper.setSubject(simpleMailMessage.getSubject());
			helper.setText(stokMailGenerator.getMessage());
		} catch (Exception e) {
			log.error("sending mail has been failed", e);
			return new MailStatus("failed", "sending mail has been failed");
		}
		
		javaMailSender.send(mimeMessage);
		return new MailStatus("success", "mail sent successfully");
	}
	
	@GET
	@Produces(MediaType.APPLICATION_XML)
	public MailConfigurationModel getMailConfiguration() {
		MailConfigurationModel model = new MailConfigurationModel();
		model.setHost(propertyUtil.getProperty(MAIL_HOST));
		model.setAuthentication(Boolean.getBoolean(propertyUtil.getProperty(MAIL_AUTH)));
		model.setPassword(propertyUtil.getProperty(MAIL_PASSWORD));
		model.setPort(propertyUtil.getProperty(MAIL_PORT));
		List<String> receipients = null;
		if(propertyUtil.getProperty(MAIL_RECIPIENT).contains(",")) {
			receipients = Arrays.asList(propertyUtil.getProperty(MAIL_RECIPIENT).split(","));
		} else {
			receipients = new ArrayList<String>();
			receipients.add(propertyUtil.getProperty(MAIL_RECIPIENT));
		}
		model.setReceipients(receipients);
		model.setSecureConnection(Boolean.getBoolean(propertyUtil.getProperty(MAIL_TLS)));
		model.setSender(propertyUtil.getProperty(MAIL_SENDER));
		model.setSubject(propertyUtil.getProperty(MAIL_SUBJECT));
		model.setUsername(propertyUtil.getProperty(MAIL_USER));
		return model;
	}
	
	@POST
	@Produces(MediaType.APPLICATION_XML)
	@Consumes(MediaType.APPLICATION_XML)
	public MailStatus setMailConfiguration(JAXBElement<MailConfigurationModel> xml) {
		MailConfigurationModel model = xml.getValue();
		Properties props = new Properties();
		StringBuilder receipientBuilder = new StringBuilder();
		for(String receipient : model.getReceipients()) {
			receipientBuilder.append(receipient);
			if(model.getReceipients().indexOf(receipient) < model.getReceipients().size() - 1){
				receipientBuilder.append(",");
			}
		}
		props.put(MAIL_HOST, model.getHost());
		props.put(MAIL_AUTH, model.isAuthentication());
		props.put(MAIL_PASSWORD, model.getPassword());
		props.put(MAIL_PORT, model.getPort());
		log.info("receipient : "+ receipientBuilder.toString());
		props.put(MAIL_RECIPIENT, receipientBuilder.toString());
		props.put(MAIL_SENDER, model.getSender());
		props.put(MAIL_SUBJECT, model.getSubject());
		props.put(MAIL_TLS, model.isSecureConnection());
		props.put(MAIL_USER, model.getUsername());
		try {
			propertyUtil.setProperties(props);
		} catch (Exception e) {
			log.error("can not update properties");
			return new MailStatus("failed", "can not update properties");
		}
		return new MailStatus("success", "configuration changed successfully");
	}
	
}
